﻿using Microsoft.AspNetCore.Http;
using Microsoft.Net.Http.Headers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common.Framework.Core.Extension
{
    public static class HttpRequestExtension
    {
        /// <summary>
        /// 获取当前 referer.
        /// </summary>
        /// <value>
        public static string GetReferer(this HttpRequest request)
        {
            if (null == request || !request.Headers.Keys.Contains(HeaderNames.Referer))
            {
                return string.Empty;
            }
            return request.Headers[HeaderNames.Referer].ToString();
        }

        /// <summary>
        ///  获取当前 UserAgent.
        /// </summary>
        public static string GetUserAgent(this HttpRequest request)
        {
            if (null == request || !request.Headers.Keys.Contains(HeaderNames.UserAgent))
            {
                return string.Empty;
            }
            return request.Headers[HeaderNames.UserAgent].ToString();
        }

        /// <summary>
        /// 获取IP地址
        /// 这RemoteIpAddress是在类型IPAddress，而不是string。它包含了IPv4，IPv6等信息
        /// </summary>
        public static string GetRemoteIpAddress(this HttpRequest request)
        {
            var ip = "";
            if (null != request && null != request.HttpContext.Connection)
            {
                if (string.IsNullOrWhiteSpace(ip))
                {
                    ip = request.Headers["X-SLB-IP"];//阿里云SLB-Kong转发,优先级最高
                }

                if (string.IsNullOrWhiteSpace(ip))
                {
                    ip = request.Headers["X-Forwarded-For"];//常规IP转发取值
                    if (!string.IsNullOrWhiteSpace(ip))//如果常规转发有值，则取第一层 （原因，转发会将所有层级的ip相加在一起，用英文逗号隔开）
                    {
                        ip = ip.Replace("，", ",");
                        var ips = ip.Split(',');
                        if (ips.Length > 0)
                        {
                            ip = ips[0];
                        }
                    }
                }
                if (string.IsNullOrWhiteSpace(ip))
                {
                    ip = request.Headers["HTTP_X_FORWARDED_FOR"];//获取包括使用了代理服务器的地址列表。
                }
                if (string.IsNullOrWhiteSpace(ip))
                {
                    ip = request.Headers["REMOTE_ADDR"];//最后一个代理服务器地址。
                }

                if (string.IsNullOrWhiteSpace(ip))
                {
                    //指定IPV4
                    ip = request.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
                }
            }
            return ip;
        }

        /// <summary>
        /// 是否是Local
        /// </summary>
        public static bool IsLocal(this HttpRequest request)
        {
            return request.GetAbsoluteUri().Contains("localhost");
        }

        /// <summary>
        /// 获取请求的完整URL
        /// </summary>
        public static string GetAbsoluteUri(this HttpRequest request)
        {
            if (null != request)
            {
                string host = request.Headers["X-Referer-Host"].FirstOrDefault();
                StringBuilder str = new StringBuilder();
                if (string.IsNullOrWhiteSpace(host))//网关透传Host不存在，则直接从当前获取
                {
                    str.Append(request.Scheme).Append("://").Append(request.Host);
                }
                else
                {
                    str.Append(host);
                }
                str.Append(request.PathBase).Append(request.Path)
                    .Append(request.QueryString);

                return str.ToString();
            }
            return string.Empty;
        }

        /// <summary>
        /// 获取当前的域名
        /// </summary>
        public static string GetBaseUri(this HttpRequest request)
        {
            if (null != request)
            {
                return new StringBuilder()
                    .Append(request.Scheme)
                    .Append("://")
                    .Append(request.Host)
                    .Append(request.PathBase)
                    .ToString();
            }
            return string.Empty;
        }
    }
}
